Android NFC读MifareClassic卡获取卡片ID 类型 扇区 存储空间

您所在的位置:网站首页 nfc 读取id卡 Android NFC读MifareClassic卡获取卡片ID 类型 扇区 存储空间

Android NFC读MifareClassic卡获取卡片ID 类型 扇区 存储空间

2024-07-10 02:19| 来源: 网络整理| 查看: 265

1.首先要在AndroidManifest.xml中声明如下配置信息:

为了能够使用Android手机的NFC功能,需要在Manifest文件中添加相应的权限:

详细配置请参考-->Android NFC标签读写配置过滤器总结

2.NFC TAG的发布系统:

当android设备扫描到一个NFC标签时,会自动寻找最适合的Activity来处理这个TAG,如果有多个Activity满足条件的话,会让用户来选择到底使用哪一个Activity来处理,可以理解为就是简单的事件响应与事件处理。

那么如何让一个Activity监听 ”当扫描到NFC标签时” 的这一个事件呢?使用intent filter。

可以理解为当检测到一个NFC标签时,系统自动创建一个相关Intent对象,含有响应intent-filter的Activity将处理这个Intent。

其中,intent filter声明如下:(在AndroidManifest.xml中声明在你需要捕获这个Intent的Activity里)(如下是识别公交卡的TECH格式过滤标签)即ACTION_TECH_DISCOVERED类型的过滤器:

配置android:name=".NFCActivity"是为了当退出app时只要扫描卡片能直接打开app并定位到NFC扫描界面。

在res文件夹下新建一个xml的文件夹,里面放的是Android支持的NFC类型的配置数据。nfc_tech_filter.xml如下:

android.nfc.tech.IsoDep android.nfc.tech.NfcA android.nfc.tech.NfcB android.nfc.tech.NfcF android.nfc.tech.NfcV android.nfc.tech.Ndef android.nfc.tech.NdefFormatable android.nfc.tech.MifareUltralight android.nfc.tech.MifareClassic

另外还有ACTION_NDEF_DISCOVERED类型的过滤器

ACTION_TAG_DISCOVERED类型的过滤器 3.详细代码如下:

res/layout/nfc_info.xml

NFCActivity.java

import android.app.Activity; import android.app.PendingIntent; import android.content.Intent; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.MifareClassic; import android.os.Bundle; import android.view.View; import android.widget.TextView; import android.widget.Toast; public class NFCActivity extends Activity { NfcAdapter nfcAdapter; TextView promt; private PendingIntent pi; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.nfc_info); promt = (TextView) findViewById(R.id.promt); // 获取默认的NFC控制器 nfcAdapter = NfcAdapter.getDefaultAdapter(this); pi = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); if (nfcAdapter == null) { Toast.makeText(this, "对不起,您的设备不支持nfc功能!", Toast.LENGTH_SHORT).show(); //promt.setText("设备不支持NFC!"); finish(); return; } if (!nfcAdapter.isEnabled()) { Toast.makeText(this, "请在系统设置中开启NFC功能!", Toast.LENGTH_SHORT).show(); //promt.setText("请在系统设置中先启用NFC功能!"); finish(); return; } } public void btn_back(View view){ this.finish(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来 // 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法 if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { processIntent(intent); } } //页面获取焦点 @Override protected void onResume() { super.onResume(); nfcAdapter.enableForegroundDispatch(this, pi, null, null); } //页面失去焦点 @Override protected void onPause() { super.onPause(); if(nfcAdapter!=null){ nfcAdapter.disableForegroundDispatch(this);//关闭前台发布系统 } } /*@Override protected void onResume() { super.onResume(); //得到是否检测到ACTION_TECH_DISCOVERED触发 if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) { //处理该intent processIntent(getIntent()); } }*/ //字符序列转换为16进制字符串 private String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder("0x"); if (src == null || src.length >> 4) & 0x0F, 16); buffer[1] = Character.forDigit(src[i] & 0x0F, 16); System.out.println(buffer); stringBuilder.append(buffer); } return stringBuilder.toString(); } private String ByteArrayToHexString(byte[] inarray) { int i, j, in; String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; String out = ""; for (j = 0; j < inarray.length; ++j) { in = (int) inarray[j] & 0xff; i = (in >> 4) & 0x0f; out += hex[i]; i = in & 0x0f; out += hex[i]; } return out; } /** * Parses the NDEF Message from the intent and prints to the TextView */ private void processIntent(Intent intent) { //取出封装在intent中的TAG Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); String CardId =ByteArrayToHexString(tagFromIntent.getId()); String metaInfo = ""; metaInfo+="卡片ID:"+CardId; for (String tech : tagFromIntent.getTechList()) { System.out.println(tech); } boolean auth = false; //读取TAG MifareClassic mfc = MifareClassic.get(tagFromIntent); try { //Enable I/O operations to the tag from this TagTechnology object. mfc.connect(); int type = mfc.getType();//获取TAG的类型 int sectorCount = mfc.getSectorCount();//获取TAG中包含的扇区数 String typeS = ""; switch (type) { case MifareClassic.TYPE_CLASSIC: typeS = "TYPE_CLASSIC"; break; case MifareClassic.TYPE_PLUS: typeS = "TYPE_PLUS"; break; case MifareClassic.TYPE_PRO: typeS = "TYPE_PRO"; break; case MifareClassic.TYPE_UNKNOWN: typeS = "TYPE_UNKNOWN"; break; } metaInfo += "\n卡片类型:" + typeS + "\n共" + sectorCount + "个扇区\n共" + mfc.getBlockCount() + "个块\n存储空间: " + mfc.getSize() + "B\n"; for (int j = 0; j < sectorCount; j++) { //Authenticate a sector with key A. auth = mfc.authenticateSectorWithKeyA(j, MifareClassic.KEY_DEFAULT); int bCount; int bIndex; if (auth) { metaInfo += "Sector " + j + ":验证成功\n"; // 读取扇区中的块 bCount = mfc.getBlockCountInSector(j); bIndex = mfc.sectorToBlock(j); for (int i = 0; i < bCount; i++) { byte[] data = mfc.readBlock(bIndex); metaInfo += "Block " + bIndex + " : " + bytesToHexString(data) + "\n"; bIndex++; } } else { metaInfo += "Sector " + j + ":验证失败\n"; } } promt.setText(metaInfo); //Toast.makeText(this, metaInfo, Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } } }

4.运行效果图如下:

image.png


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3